import { assign, forEach } from 'min-dash';

import { is } from './../util/ModelUtil';

import { isExpanded, isEventSubProcess } from './../util/DiUtil';

import { isAny } from './../util/ModelingUtil';

import { getChildLanes } from './../util/LaneUtil';

import { getTranslate } from './../util/TranslateUtil';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
export default function ContextPadProvider(
  this: any,
  config: { autoPlace?: any },
  injector: { get: (arg0: string, arg1: boolean) => any },
  _eventBus: { on: (arg0: string, arg1: number, arg2: (event: any) => void) => void },
  contextPad: {
    registerProvider: (arg0: any) => void;
    isOpen: (arg0: any) => any;
    getEntries: (arg0: any) => any;
  },
  modeling: any,
  elementFactory: any,
  connect: any,
  create: any,
  popupMenu: any,
  canvas: any,
  rules: any,
) {
  config = config || {};

  contextPad.registerProvider(this);

  this._contextPad = contextPad;

  this._modeling = modeling;

  this._elementFactory = elementFactory;
  this._connect = connect;
  this._create = create;
  this._popupMenu = popupMenu;
  this._canvas = canvas;
  this._rules = rules;

  if (config.autoPlace !== false) {
    this._autoPlace = injector.get('autoPlace', false);
  }
}

ContextPadProvider.$inject = [
  'config.contextPad',
  'injector',
  'eventBus',
  'contextPad',
  'modeling',
  'elementFactory',
  'connect',
  'create',
  'rules',
];

ContextPadProvider.prototype.getContextPadEntries = function (element: {
  type: string;
  businessObject: any;
  id: any;
  height: number;
}) {
  const contextPad = this._contextPad,
    modeling = this._modeling,
    elementFactory = this._elementFactory,
    connect = this._connect,
    create = this._create,
    autoPlace = this._autoPlace;

  const actions = {};

  if (element.type === 'label') {
    return actions;
  }

  if (is(element, 'bpmn:EndEvent') || is(element, 'bpmn:SequenceFlow')) {
    return {
      delete: {
        group: 'event2',
        className: 'bpmn-icon-trash',
        title: getTranslate(t('删除')),
        action: {
          click: removeElement,
        },
      },
      connect: {
        group: 'none',
        className: 'bpmn-icon-text-annotation',
        title: 'a',
        action: {},
      },
      replace: {
        group: 'none',
        className: 'bpmn-icon-text-annotation',
        title: 'a',
        action: {},
      },
      'append.gateway': {
        group: 'none',
        className: 'bpmn-icon-text-annotation',
        title: 'a',
        action: {},
      },
      'append.append-task': {
        group: 'none',
        className: 'bpmn-icon-text-annotation',
        title: 'a',
        action: {},
      },
      'append.intermediate-event': {
        group: 'none',
        className: 'bpmn-icon-text-annotation',
        title: 'a',
        action: {},
      },
      'append.text-annotation': {
        group: 'none',
        className: 'bpmn-icon-text-annotation',
        title: 'a',
        action: {},
      },
    };
  }

  const businessObject = element.businessObject;

  function startConnect(event: any, element: any) {
    connect.start(event, element);
  }
  function removeElement() {
    modeling.removeElements([element]);
  }

  function appendAction(type: string, className: string, title: string, options?: undefined) {
    if (typeof title !== 'string') {
      options = title;
      title = getTranslate('Append {type}', { type: type.replace(/^bpmn:/, '') });
    }

    function appendStart(event: any, element: any) {
      const shape = elementFactory.createShape(assign({ type: type }, options));
      create.start(event, shape, {
        source: element,
      });
    }

    const append = autoPlace
      ? function (_event: any, element: any) {
          const shape = elementFactory.createShape(assign({ type: type }, options));
          autoPlace.append(element, shape);
        }
      : appendStart;

    return {
      group: 'event1',
      className: className,
      title: title,
      action: {
        dragstart: appendStart,
        click: append,
      },
    };
  }

  function splitLaneHandler(count: number) {
    return function (_event: any, element: any) {
      // actual split
      modeling.splitLane(element, count);

      // refresh context pad after split to
      // get rid of split icons
      contextPad.open(element, true);
    };
  }

  if (isAny(businessObject, ['bpmn:Lane', 'bpmn:Participant']) && isExpanded(businessObject)) {
    const childLanes = getChildLanes(element);

    if (childLanes.length < 2) {
      if (element.height >= 120) {
        assign(actions, {
          'lane-divide-two': {
            group: 'lane-divide',
            className: 'bpmn-icon-lane-divide-two',
            title: getTranslate('Divide into two Lanes'),
            action: {
              click: splitLaneHandler(2),
            },
          },
        });
      }

      if (element.height >= 180) {
        assign(actions, {
          'lane-divide-three': {
            group: 'lane-divide',
            className: 'bpmn-icon-lane-divide-three',
            title: getTranslate('Divide into three Lanes'),
            action: {
              click: splitLaneHandler(3),
            },
          },
        });
      }
    }

    assign(actions, {});
  }
  if (isAny(businessObject, ['bpmn:Lane', 'bpmn:Participant'])) {
  }
  if (is(businessObject, 'bpmn:FlowNode')) {
    if (is(businessObject, 'bpmn:EventBasedGateway')) {
    } else if (
      isEventType(businessObject, 'bpmn:BoundaryEvent', 'bpmn:CompensateEventDefinition')
    ) {
    } else if (
      !is(businessObject, 'bpmn:EndEvent') &&
      !businessObject.isForCompensation &&
      !isEventType(businessObject, 'bpmn:IntermediateThrowEvent', 'bpmn:LinkEventDefinition') &&
      !isEventSubProcess(businessObject)
    ) {
      assign(actions, {
        'append.end-event': appendAction(
          'bpmn:EndEvent',
          'bpmn-icon-end-event-none',
          getTranslate(t('创建结束节点')),
        ),
        'append.script-task': appendAction(
          'bpmn:ScriptTask',
          'bpmn-icon-script',
          getTranslate(t('创建脚本节点')),
        ),
        'append.user-task': appendAction(
          'bpmn:UserTask',
          'bpmn-icon-user',
          getTranslate(t('创建用户节点')),
        ),
        'append.exclusive-gateway': appendAction(
          'bpmn:ExclusiveGateway',
          'bpmn-icon-gateway-xor',
          getTranslate(t('互斥网关')),
        ),
        'append.inclusive-gateway': appendAction(
          'bpmn:InclusiveGateway',
          'bpmn-icon-gateway-or',
          getTranslate(t('相容网关')),
        ),
        'append.parallel-gateway': appendAction(
          'bpmn:ParallelGateway',
          'bpmn-icon-gateway-parallel',
          getTranslate(t('并行网关')),
        ),
        connect: {
          group: 'event2',
          className: 'bpmn-icon-connection-multi',
          title: getTranslate(t('连接线')),
          action: {
            click: startConnect,
            dragstart: startConnect,
          },
        },
        delete: {
          group: is(element, 'bpmn:StartEvent') ? 'none' : 'event2',
          className: 'bpmn-icon-trash',
          title: getTranslate(t('删除')),
          action: {
            click: removeElement,
          },
        },
      });
    }
  }

  // if (!popupMenu.isEmpty(element, "bpmn-replace")) {
  // }

  if (
    isAny(businessObject, [
      'bpmn:FlowNode',
      'bpmn:InteractionNode',
      'bpmn:DataObjectReference',
      'bpmn:DataStoreReference',
    ])
  ) {
    // 将默认属性隐藏
    const displayNone = {
      group: 'none',
      className: '',
      title: getTranslate(''),
      action: {},
    };
    assign(actions, {
      'append.text-annotation': displayNone,
      'append.gateway': displayNone,
      'append.append-task': displayNone,
      'append.intermediate-event': displayNone,
      replace: displayNone,
    });
  }
  //  console.log('actions',actions);
  // if(actions&&actions){
  //   delete actions['append.text-annotation'];
  // }

  return actions;
};

// helpers /////////

function isEventType(
  eventBo: { $instanceOf: (arg0: any) => any; eventDefinitions: never[] },
  type: string,
  definition: string,
) {
  const isType = eventBo.$instanceOf(type);
  let isDefinition = false;

  const definitions = eventBo.eventDefinitions || [];
  forEach(definitions, function (def: { $type?: any }) {
    if (def.$type === definition) {
      isDefinition = true;
    }
  });

  return isType && isDefinition;
}
